home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / 80x0393.zip / CPUID.ASM < prev    next >
Assembly Source File  |  1993-03-30  |  11KB  |  240 lines

  1. TITLE   CPUID
  2. ;v5.93  Toad Hall Tweak, 1 Jul 91
  3. ;       - Tightened up code a little, tabified.
  4. ;         I have *no* idea what he did to make the original
  5. ;         CPUID.EXE 6Kb long!  debug enabled?
  6. ;       - Rewritten to .COM format to reduce size further.
  7. ;       We *really* should be returning a magic number as ERRORLEVEL
  8. ;       so a batch file could process accordingly.
  9. ;       David Kirschbaum
  10. ;       kirschd@sesi.com
  11.  
  12. ;v5.94  DD Tweak, 8 Jan 92, to return errorlevels
  13. ;       This version assembles with Eric Isaacson's A86
  14. ;       Fixed the problem with "period" not always being printed
  15. ;       Doug Dougherty, valley@gsbsun.uchicago.edu
  16.  
  17. CSEG    SEGMENT
  18.         ASSUME  CS:CSEG,DS:CSEG,ES:CSEG
  19.  
  20.         org     100H                    ;.COM file
  21.  
  22. cpuid   proc    near
  23.         jmp     start                   ;skip over data
  24.  
  25. exitcode        db      0               ;v5.94
  26.  
  27. fp_status       dw      0
  28. id_mess         db      "CPUID v5.94 (Toad Hall, DD tweaks)"            ;v5.94
  29.                 db      13,10,13,10,"This system has a$"                ;v5.94
  30. fp_8087         db      " and an 8087 math coprocessor$"
  31. fp_80287        db      " and an i287tm math coprocessor$"
  32. fp_80387        db      " and an i387tm math coprocessor$"
  33. c8086           db      "n 8086/8088 microprocessor$"
  34. c286            db      "n 80286 microprocessor$"
  35. c386            db      " i386tm microprocessor$"
  36. c486            db      " i486tm DX microprocessor or i487tm SX math coprocessor$"
  37. c486nfp         db      " i486tm SX microprocessor$"
  38. period          db      ".",13,10,"$"
  39. present_86      db      0       ;v5.92
  40. present_286     db      0       ;v5.92
  41. present_386     db      0       ;v5.92
  42. present_486     db      0       ;v5.92
  43.  
  44. cpuid   endp
  45.  
  46. ;
  47. ; The purpose of this code is to allow the user the ability to identify the
  48. ; processor and coprocessor that is currently in the system.  The algorithm
  49. ; of the program is to first determine the processor id.
  50. ; When that is accomplished, the program continues to then identify whether
  51. ; a coprocessor exists in the system.  If a coprocessor or integrated
  52. ; coprocessor exists, the program will identify the coprocessor id.  If one
  53. ; does not exist, the program then terminates.
  54. ;
  55. start   proc    near
  56.  
  57.         mov     dx,offset id_mess               ; print header message
  58.         mov     ah,9h
  59.         int     21h
  60.  
  61. ;
  62. ;       8086 CPU check
  63. ;       Bits 12-15 are always set on the 8086 processor.
  64. ;
  65.         mov     cx,0F000H               ;handy constant                 v5.93
  66.         pushf                           ; save EFLAGS
  67.         pop     bx                      ; store EFLAGS in BX
  68.         mov     ax,0fffh                ; clear bits 12-15
  69.         and     ax,bx                   ;       in EFLAGS
  70.         push    ax                      ; store new EFLAGS value on stack
  71.         popf                            ; replace current EFLAGS value
  72.         pushf                           ; set new EFLAGS
  73.         pop     ax                      ; store new EFLAGS in AX
  74.         and     ax,cx   ;0f000h         ; if bits 12-15 are set,        v5.93
  75.         cmp     ax,cx   ;0f000h         ; then CPU is an 8086/8088      v5.93
  76.         mov     dx,offset c8086         ; store 8086/8088 message
  77.         mov     present_86,1            ; turn on 8086/8088 flag
  78.         mov     exitcode,1              ; Setup exitcode for 8086/8088  v5.94
  79.         je      check_fpu               ; if CPU is 8086/8088, check for 8087
  80.  
  81. ;
  82. ;       80286 CPU check
  83. ;       Bits 12-15 are always clear on the 80286 processor.
  84. ;
  85.  
  86.         or      bx,cx   ;0f000h         ; try to set bits 12-15         v5.93
  87.         push    bx
  88.         popf
  89.         pushf
  90.         pop     ax
  91.         and     ax,cx   ;0f000h         ; if bits 12-15 are cleared     v5.93
  92.         mov     dx,offset c286          ; then CPU is an 80286
  93.         mov     present_86,0            ; turn off 8086/8088 flag
  94.         mov     present_286,1           ; turn on 80286 flag
  95.         mov     exitcode,2              ; Setup exitcode for 80286      v5.94
  96.         jz      check_fpu               ; if CPU is 80286, check for 80287
  97.  
  98. ;
  99. ; i386 CPU check
  100. ; The AC bit, bit #18, is a new bit introduced in the EFLAGS register on the
  101. ;  i486 DX CPU to generate alignment faults.  This bit can be set on the
  102. ;  i486 DX CPU, but not on the i386 CPU.
  103.  
  104.  
  105.         mov     bx,sp                   ; save current stack pointer to align it
  106.         and     sp,not 3                ; align stack to avoid AC fault
  107.         db      66h
  108.         pushf                           ; push original EFLAGS
  109.         db      66h
  110.         pop     ax                      ; get original EFLAGS
  111.         db      66h
  112.         mov     cx,ax                   ; save original EFLAGS
  113.         db      66h                     ; xor EAX,40000h
  114.         xor     ax,0                    ; flip AC bit in EFLAGS
  115.         dw      4                       ; upper 16-bits of xor constant
  116.         db      66h
  117.         push    ax                      ; save for EFLAGS
  118.         db      66h
  119.         popf                            ; copy to EFLAGS
  120.         db      66h
  121.         pushf                           ; push EFLAGS
  122.         db      66h
  123.         pop     ax                      ; get new EFLAGS value
  124.         db      66h
  125.         xor     ax,cx                   ; if AC bit cannot be changed, CPU is
  126.         mov     dx,offset c386          ; store i386 message
  127.         mov     present_286,0           ; turn off 80286 flag
  128.         mov     present_386,1           ; turn on i386 flag
  129.         mov     exitcode,3              ; Setup exitcode for 80386      v5.94
  130.         je      check_fpu               ; if CPU is i386, now check for
  131.                                         ;       80287/80387 MCP
  132.  
  133. ;
  134. ;       i486 DX CPU / i487 SX MCP and i486 SX CPU checking
  135. ;
  136.         mov     dx,offset c486nfp       ; store 486NFP message
  137.         mov     present_386,0           ; turn off i386 flag
  138.         mov     present_486,1           ; turn on i486 flag
  139.         mov     exitcode,4              ; Setup exitcode for 80486      v5.94
  140.  
  141. ;
  142. ; Co-processor checking begins here for the 8086/80286/i386 CPUs.
  143. ; The algorithm is to determine whether or not the floating-point status
  144. ; and control words can be written to.  If they are not, no coprocessor exists.
  145. ; If the status and control words can be written to, the correct coprocessor
  146. ; is then determined depending on the processor id.  Coprocessor checks are
  147. ; first performed for an 8086, 80286 and a i486 DX CPU.  If the coprocessor id
  148. ; is still undetermined, the system must contain a i386 CPU.  The i386 CPU may
  149. ; work with either an 80287 or an 80387.  The infinity of the coprocessor must
  150. ; be checked to determine the correct coprocessor id.
  151. ;
  152.  
  153. check_fpu:                              ; check for 8087/80287/80387
  154.         fninit                          ; reset FP status word
  155.         mov     fp_status,5a5ah         ; initialize temp word to non-zero value
  156.         fnstsw  fp_status               ; save FP status word
  157.         mov     ax,fp_status            ; check FP status word
  158. ;v5.93  cmp     al,0
  159.         or      al,al                   ; see if correct status with written v5.93
  160.         jne     print_one               ; jump if not Valid, no NPX installed
  161.  
  162.         fnstcw  fp_status               ; save FP control word
  163.         mov     ax,fp_status            ; check FP control word
  164.         and     ax,103fh                ; see if selected parts looks OK
  165.         cmp     ax,3fh                  ; check that ones and zeroes correctly
  166.                                         ; read
  167.         jne     msgterm                 ; not valid, no NPX installed   v5.93
  168.  
  169.         cmp     present_486,1           ; check if i486 flag is on
  170.         jne     not_486                 ;nope, continue 386 checking    v5.93
  171.                                         ;yep, display i486 msg          v5.93
  172.          mov    dx,offset c486          ; store i486 message
  173.          jmp    msgterm                 ;display i486 message, terminate v5.9